package xyz.thetbw.autocode.velocity

import xyz.thetbw.autocode.utils.StringCaseUtils
import org.apache.velocity.context.InternalContextAdapter
import org.apache.velocity.exception.ParseErrorException
import org.apache.velocity.runtime.directive.Directive
import org.apache.velocity.runtime.directive.DirectiveConstants
import org.apache.velocity.runtime.parser.node.ASTBlock
import org.apache.velocity.runtime.parser.node.Node
import java.io.StringWriter
import java.io.Writer
import java.util.*

/**
 * 一些自定义指令， 暂时废弃
 */


fun getParamStr(node: Node,context: InternalContextAdapter?): String{
    context!!
    val param = node.jjtGetChild(0);
    var str: String
    if (param is ASTBlock) {
        val blockContent = StringWriter()
        param.render(context,blockContent)
        str = blockContent.toString()
    }else{
        str = param.value(context)?.toString() ?: ""
    }
    return str
}

//转换为大写
class Uppercase: Directive(){
    override fun getName() = "uppercase"
    override fun getType() = DirectiveConstants.BLOCK

    override fun render(context: InternalContextAdapter?, writer: Writer?, node: Node?): Boolean {
        val argNum = node!!.jjtGetNumChildren()
        if (argNum != 1){
            throw ParseErrorException("argument length must be one")
        }
        val param = node.jjtGetChild(0)
        var str = getParamStr(param,context)
        writer!!.append(str.uppercase(Locale.getDefault()))
        return true
    }
}

//下划线转换为驼峰
class LineToHump: Directive() {
    override fun getName() = "lineToHump"
    override fun getType() = DirectiveConstants.BLOCK
    override fun render(context: InternalContextAdapter?, writer: Writer?, node: Node?): Boolean {
        node!!
        val argNum = node.jjtGetNumChildren()
        if (argNum != 1){
            throw ParseErrorException("argument length must be one")
        }
        val param = node.jjtGetChild(0)
        var str = getParamStr(param,context)
        writer!!.append(StringCaseUtils.lineToHump(str))
        return true
    }

}

//首字母大写
class UppercaseFirst: Directive(){
    override fun getName() = "uppercaseFirst"
    override fun getType() = DirectiveConstants.BLOCK
    override fun render(context: InternalContextAdapter?, writer: Writer?, node: Node?): Boolean {
        node!!
        val argNum = node.jjtGetNumChildren()
        if (argNum != 1){
            throw ParseErrorException("argument length must be one")
        }
        val param = node.jjtGetChild(0)
        var str = getParamStr(param,context)
        writer!!.append(StringCaseUtils.uppercaseFirst(str))
        return true
    }
}

class LowercaseFirst: Directive(){
    override fun getName() = "lowercaseFirst"
    override fun getType() = DirectiveConstants.BLOCK
    override fun render(context: InternalContextAdapter?, writer: Writer?, node: Node?): Boolean {
        node!!
        val argNum = node.jjtGetNumChildren()
        if (argNum != 1){
            throw ParseErrorException("argument length must be one")
        }
        val param = node.jjtGetChild(0)
        var str = getParamStr(param,context)
        writer!!.append(StringCaseUtils.lowercaseFirst(str))
        return true
    }
}
